#pragma once
#if 0

#pragma warning(disable:4251)
#include <unordered_map>
#include "Camera.h"
#include "matrix.h"
#include <windows.h>
#include "Vector2.h"
#include "DllExport.h"

namespace NBE
{
	class NBE_API Mouse
	{
	public:
		typedef unsigned int ButtonId;
		Mouse( HWND hwnd);
		unsigned int getNumButtons() const;
		vec2f getPosition() const;
		bool didGoUp( ButtonId button) const;
		bool didGoDown( ButtonId button ) const;
		bool isDown( ButtonId button ) const;

		void updateState();//TODO remove if unneeded
		void ProcessMessages(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
	private:
		static const UINT MAX_BUTTONS = 3;
		HWND m_hWnd;
		bool m_buttonStates[ MAX_BUTTONS ];		// true is down
		bool m_lastButtonStates[ MAX_BUTTONS ];
	};

	Mouse& GetTheMouse(HWND hWnd = NULL);

	class InputController
	{
	public:
		inline static bool	IsKeyDown	(int virtualKey)
		{
			return (::GetAsyncKeyState(virtualKey) & 0x8000) == 0x8000;
		}

		inline static bool	IsKeyUp	(int virtualKey)
		{
			return (::GetAsyncKeyState(virtualKey) & 0x8000) != 0x8000;
		}

		static void update(Camera& camera)
		{
			static float KEY_BOARD_IMPULSE_SCALAR =  0.5f;
			vec3f modelImpuse(0,0,0);

			static const int coord_dir = 1;
			if(IsKeyDown('M'))
			{
				KEY_BOARD_IMPULSE_SCALAR = 0.1f ;//remove later
			}
			if(IsKeyDown(VK_DOWN))
			{
				KEY_BOARD_IMPULSE_SCALAR -= 0.05f ;//remove later
				if(KEY_BOARD_IMPULSE_SCALAR<0)KEY_BOARD_IMPULSE_SCALAR = 0;
			}
			if(IsKeyDown(VK_UP))
			{
				KEY_BOARD_IMPULSE_SCALAR += 0.05f ;//remove later
			}

			if(IsKeyDown('W'))
			{
				modelImpuse.z -= KEY_BOARD_IMPULSE_SCALAR ;
			}
			if(IsKeyDown('S'))
			{
				modelImpuse.z += KEY_BOARD_IMPULSE_SCALAR ;
			}
			if(IsKeyDown('A'))
			{
				modelImpuse.x -= KEY_BOARD_IMPULSE_SCALAR;
			}
			if(IsKeyDown('D'))
			{
				modelImpuse.x += KEY_BOARD_IMPULSE_SCALAR;
			}
			if(IsKeyDown(VK_SPACE))
			{
				modelImpuse.y += KEY_BOARD_IMPULSE_SCALAR;
			}
			if(IsKeyDown(VK_CONTROL) || IsKeyDown('C'))
			{
				modelImpuse.y -= KEY_BOARD_IMPULSE_SCALAR;
			}

			if (KEY_BOARD_IMPULSE_SCALAR == 0.1f)
			{
				camera.applyWorldBasisImpulse(modelImpuse);
			}
			else
			{
				camera.applyImpulse(modelImpuse);
			}
			

			//rotate the camera

			POINT mousePos;
			::GetCursorPos(&mousePos);

			//how fast did the mouse move?

			const float MOUSE_ROTATION_SCALAR =  -0.1f ;
			vec3f mouseDelta( MOUSE_ROTATION_SCALAR * (mousePos.y-MOUSE_Y),
				MOUSE_ROTATION_SCALAR * (mousePos.x-MOUSE_X),0);
			
			camera.rotate(mouseDelta);
			//re-center the mouse
 
			//trace(camera.getRotation().x<<","<<camera.getRotation().y<<","<<camera.getRotation().z);
			::SetCursorPos(MOUSE_X,MOUSE_Y);

			//if key up, reset the keyMap value
			std::unordered_map<int,bool>::iterator it = keyMap.begin();
			while (it!= keyMap.end())
			{
				if (IsKeyUp(it->first))
				{
					it->second = false;
				}
				++it;
			}
		}

		static void setRect(LONG _X, LONG _Y)
		{
			MOUSE_X = _X;
			MOUSE_Y = _Y;
		}

		static bool getKeyMap(int key)
		{
			return keyMap[key];
		}

		static void setKeyMap(int f, bool s)
		{
			keyMap[f] = s;
		}

		static void calculateCenter( HWND hwnd )
		{

			RECT cRect,wRect;
			GetClientRect( hwnd, &cRect );
			GetWindowRect(hwnd, &wRect);
			int border_thickness = (wRect.right - wRect.left - cRect.right) /2;

			LONG MOUSE_CENTER_X = cRect.right / 2 + border_thickness + wRect.left; 
			LONG MOUSE_CENTER_Y = (cRect.bottom - cRect.top +45) / 2 + wRect.top;
			InputController::setRect(MOUSE_CENTER_X, MOUSE_CENTER_Y);
			::SetCursorPos(MOUSE_CENTER_X,MOUSE_CENTER_Y);
		}
	private:
		static LONG MOUSE_X;
		static LONG MOUSE_Y;
		static std::unordered_map<int, bool> keyMap; 
	};

}
#endif

#pragma once
#include <queue>
#include <vector>
#include "Listener.h"
#include <windows.h>
#pragma warning(disable:4251)
namespace NBE
{
	enum InputType//devices
	{
		MOUSE = 0,
		KEYBOARD,
		JOYSTICK
	};
	class NBE_API Input
	{
	public:
		Input(InputType t);
		virtual ~Input()
		{
			m_listener.clear();
		}
		virtual void update()=0;
		virtual void processMessages(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)=0;
		unsigned int addEvent(Event* theEvent);
		InputType getType();
		void handleAllEvents();
		void registerListener(Listener* lsn);
		void unRegisterListener(Listener* lsn);

	private:
		std::queue<Event*> m_eventQue;
		InputType m_inputType;
		std::vector<Listener*> m_listener;
	};
}